#include "app_flash.h"
#include "app_work.h"
#include "bsp_flash.h"

USER_FLASH_ST user_flash_info;
USER_FLASH_ST* app_user_flash_get(void) {
    return &user_flash_info;
}
//用户数据初始化
void app_user_flash_init(void) {
  memset(&user_flash_info, 0, sizeof(USER_FLASH_ST));
  app_flash_read_buf(USER_DATA_PAGE, (uint8_t *)&user_flash_info,
                     sizeof(USER_FLASH_ST));
  if (user_flash_info.dev_flash_check_flage != FLASH_CHECK_FLAGE) {
    user_flash_info.dev_sweep_speed = 50;
    user_flash_info.dev_x_step = 50;
    user_flash_info.dev_y_step = 50;
    user_flash_info.dev_Y_step_Time = Y_AXIS_MOVE_TIME;
    user_flash_info.dev_flash_check_flage = FLASH_CHECK_FLAGE;
    app_user_flash_save();
  }
}

void app_user_flash_save(void) {
#if 1
  app_flash_erase(USER_DATA_PAGE);
  app_flash_write_buf(USER_DATA_PAGE, (uint8_t *)&user_flash_info,
                      sizeof(USER_FLASH_ST));
#endif
}
void app_flash_init(void) {
  // uint8_t i=0;
  // uint32_t u32Data=0;

  SYS_UnlockReg();
  FMC_Open();

  if (FMC_GetBootSource()) {
    ;
  } else {
   ;
  }
#if 0
	u32Data = FMC_ReadCID();
		log_debug("  Company ID [0x%08X]", u32Data);

	// u32Data = FMC_ReadDID();
	// log_debug("  Device ID  [0x%08X]", u32Data);

	u32Data = FMC_ReadPID();
	log_debug("  Product ID [0x%08X]", u32Data);

	for (i = 0; i < 3; i++) {
		u32Data = FMC_ReadUID(i);
		log_debug("  Unique ID %d [0x%08X]", i, u32Data);
	}

	for (i = 0; i < 4; i++) {
		u32Data = FMC_ReadUCID(i);
		log_debug("  Unique Customer ID %d [0x%08X]", i, u32Data);
	}

	/* Read Data Flash base address */
	u32Data = FMC_ReadDataFlashBaseAddr();
	log_debug("  Data Flash Base Address  0x%08X", u32Data);

  FMC_APROM_END
#endif

  FMC_Close();
  SYS_LockReg();
	app_user_flash_init();
}

void app_flash_SID_get_fromUID(uint8_t *sid) {
  uint8_t i = 0, buf[12] = {0};
  uint32_t tmp_u32 = 0;

  SYS_UnlockReg();
  FMC_Open();
  for (i = 0; i < 3; i++) {
    tmp_u32 = FMC_ReadUID(i);
    buf[4 * i] = tmp_u32 & 0xFF;
    buf[4 * i + 1] = (tmp_u32 >> 8) & 0xFF;
    buf[4 * i + 2] = (tmp_u32 >> 16) & 0xFF;
    buf[4 * i + 3] = (tmp_u32 >> 24) & 0xFF;
  }
  FMC_Close();
  SYS_LockReg();
  tmp_u32 = CRC32_get(buf, 12);

  for (i = 0; i < 4; i++) {
    *(sid + i) = (tmp_u32 >> (i * 8)) & 0xFF;
  }
}

void app_flash_erase(uint8_t page) {
  uint8_t n = 0;

  SYS_UnlockReg();
  FMC_Open();

  n = (FMC_APROM_END - FMC_ReadDataFlashBaseAddr()) / FMC_FLASH_PAGE_SIZE;
  if (page >= n) {
    return;
  }
  bsp_flash_erase(FMC_ReadDataFlashBaseAddr() + FMC_FLASH_PAGE_SIZE * page);

  FMC_Close();
  SYS_LockReg();
}

//小端模式,1 page = 512
void app_flash_write_buf(uint8_t page, uint8_t *p, const uint16_t len) {
  uint8_t i = 0, j = 0;
  unsigned int u32_tmp = 0;

  if (len > FMC_FLASH_PAGE_SIZE) {
  
    return;
  }
  SYS_UnlockReg();
  FMC_Open();
  for (i = 0; i < (len / 4); i++) {
    u32_tmp = 0;
    for (j = 0; j < 4; j++) {
      u32_tmp |= *(p + i * 4 + j) << (j * 8);
    }
    bsp_flash_write_int(
        FMC_ReadDataFlashBaseAddr() + FMC_FLASH_PAGE_SIZE * page + i * 4,
        u32_tmp);
  }
  if (len % 4) {
    u32_tmp = 0;
    for (i = 0; i < (len % 4); i++) {
      u32_tmp |= *(p + (len / 4) * 4 + i) << (i * 8);
    }
    bsp_flash_write_int(FMC_ReadDataFlashBaseAddr() +
                            FMC_FLASH_PAGE_SIZE * page + (len / 4) * 4,
                        u32_tmp);
  }
  FMC_Close();
  SYS_LockReg();
}

//小端模式
void app_flash_read_buf(uint8_t page, uint8_t *p, const uint16_t len) {
  uint8_t i = 0, j = 0;
  unsigned int u32_tmp = 0;

  SYS_UnlockReg();
  FMC_Open();
  for (i = 0; i < (len / 4); i++) {
    u32_tmp = bsp_flash_read_int(FMC_ReadDataFlashBaseAddr() +
                                 FMC_FLASH_PAGE_SIZE * page + i * 4);
    for (j = 0; j < 4; j++) {
      *(p + i * 4 + j) = (u32_tmp >> (j * 8)) & 0xFF;
    }
  }
  if (len % 4) {
    u32_tmp = bsp_flash_read_int(FMC_ReadDataFlashBaseAddr() +
                                 FMC_FLASH_PAGE_SIZE * page + (len / 4) * 4);
    for (i = 0; i < (len % 4); i++) {
      *(p + (len / 4) * 4 + i) = (u32_tmp >> (i * 8)) & 0xFF;
    }
  }
  FMC_Close();
  SYS_LockReg();
}
